/**
    [Filename]
    Purpose: [Purpose]

    @author Jason Wojcik
    @version [version]
*/

#include "CArea.h"
#include <iostream>

using std::cout;

CArea CArea::AreaControl;

CArea::CArea() {
    AreaSize = 0;
}

/*
Creates a vector of maps
Area file format:
    first line: path of tile file,
    second line: height of area (integer height of maps),
    remaining lines: path o f map files (# of maps / line = area height)
Each area can have only 1 tileset
@param file path to the area file
@return  true/false
*/
bool CArea::OnLoad(char* File) {
    MapList.clear();

    //open the file
    FILE* FileHandle = fopen(File, "r");

    //return false if the file doesn't exist
    if(FileHandle == NULL) {
        return false;
    }

    //create a character array to hold the filename
    char TilesetFile[255];

    //reads the filename of the tile into TilesetFile
    fscanf(FileHandle, "%s\n", TilesetFile);

    //if the tile file doesn't exist, close the file and return false
    if((Surf_Tileset = CSurface::OnLoad(TilesetFile)) == false) {
        fclose(FileHandle);

        return false;
    }

    //read the size of the area (integer in area file)
    fscanf(FileHandle, "%d\n", &AreaSize);

    for(int X = 0;X < AreaSize;X++) {
        for(int Y = 0;Y < AreaSize;Y++) {
            char MapFile[255];

            //read the filename of the map file
            fscanf(FileHandle, "%s ", MapFile);

            //if map file load fails, close file return false
            CMap tempMap;
            if(tempMap.OnLoad(MapFile) == false) {
                fclose(FileHandle);

                return false;
            }

            tempMap.Surf_Tileset = Surf_Tileset;

            //add the map to the map vector
            MapList.push_back(tempMap);
        }
        //close the map file
        fscanf(FileHandle, "\n");
    }

    //close the area file
    fclose(FileHandle);

    return true;
}

//Renders the area, one map at a time
void CArea::OnRender(SDL_Surface* Surf_Display, int CameraX, int CameraY) {
    int MapWidth  = MAP_WIDTH * TILE_SIZE;
    int MapHeight = MAP_HEIGHT * TILE_SIZE;

    int FirstID = -CameraX / MapWidth;
        FirstID = FirstID + ((-CameraY / MapHeight) * AreaSize);

    for(int i = 0;i < 4;i++) {
        int ID = FirstID + ((i / 2) * AreaSize) + (i % 2);

        if(ID < 0 || ID >= MapList.size()) continue;

        int X = ((ID % AreaSize) * MapWidth) + CameraX;
        int Y = ((ID / AreaSize) * MapHeight) + CameraY;

        MapList[ID].OnRender(Surf_Display, X, Y);
    }
}

void CArea::OnCleanup() {
    if(Surf_Tileset) {
        SDL_FreeSurface(Surf_Tileset);
    }

    MapList.clear();
}

CMap* CArea::GetMap(int X, int Y) {
    int MapWidth  = MAP_WIDTH * TILE_SIZE;
    int MapHeight = MAP_HEIGHT * TILE_SIZE;

    int ID = X / MapWidth;
        ID = ID + ((Y / MapHeight) * AreaSize);

    if(ID < 0 || ID >= MapList.size()) {
        return NULL;
    }

    return &MapList[ID];
}

//returns the tile at the X,Y coordinate
CTile* CArea::GetTile(int X, int Y) {
    int MapWidth  = MAP_WIDTH * TILE_SIZE;
    int MapHeight = MAP_HEIGHT * TILE_SIZE;

    CMap* Map = GetMap(X, Y);

    if(Map == NULL) return NULL;

    X = X % MapWidth;
    Y = Y % MapHeight;

    return Map->GetTile(X, Y);
}

/*
Sets the color of the tile at the specified ID
@params
@return N/A
*/
void CArea::SetTileColor(int X, int Y, int Color){

    int MapWidth  = MAP_WIDTH * TILE_SIZE;
    int MapHeight = MAP_HEIGHT * TILE_SIZE;

    CMap* Map = GetMap(X, Y);

    if(Map == NULL) return;

    Map->SetTileColor(X,Y,Color);
}

/*
Returns the color specified by the TileID
Only works if there is only one map
@params ID
@return tile color (int)
*/
int CArea::GetTileColor(int ID){
    //choose the map
    CMap* Map = &MapList[0];
    //get the tile at the specified ID
    CTile* tile = Map->GetTile(ID);
    //return the color of the specified tile
    return tile->TileColor;
}



